﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * MySQL配置信息数据库提供者。
 * 
 * 最后修改：2011-10-29
 * ************************************************************/
namespace Mozlite.Data.MySqlDataProvider
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Web.Hosting;
    using MySql.Data.MySqlClient;
    using Mozlite.Common.Configuration;
    using Mozlite.Common;

    /// <summary>
    /// 配置信息数据库提供者。
    /// </summary>
    public class MySqlConfigurationDataProvider : ConfigurationDataProvider
    {
        /// <summary>
        /// 初始化类<see cref="T:Mozlite.Data.MySqlDataProvider.MySqlConfigurationDataProvider"/>。
        /// </summary>
        public MySqlConfigurationDataProvider() : base(MySqlClientFactory.Instance) { }

        #region sites
        public override CreateSiteStatus SaveSite(SiteDomain site)
        {
            if (site.SiteID > 0)
            {
                if (ExecuteNonQuery("UPDATE {0} SET `Domain` = '{1}', DotLowerDomain = '.{1}', SettingsID = '{2}', Enabled = '{3}' WHERE SiteID = '{4}';", AddProfix("Sites"), Q(site.Domain.ToLower()), site.SettingsID, Q(site.Enabled), site.SiteID))
                    return CreateSiteStatus.Updated;
            }
            else
            {
                if (ExecuteScalar<bool>("SELECT 1 FROM {0} WHERE DotLowerDomain = '.{1}';", AddProfix("Sites"), Q(site.Domain.ToLower())))
                    return CreateSiteStatus.DulplicateDomain;
                if (ExecuteNonQuery("INSERT INTO {0}(`Domain`,DotLowerDomain,SettingsID,Enabled)VALUES('{1}','.{1}','{2}','{3}');", AddProfix("Sites"), Q(site.Domain.ToLower()), site.SettingsID, Q(site.Enabled)))
                    return CreateSiteStatus.Success;
            }
            return CreateSiteStatus.Unknown;
        }

        public override bool DeleteSite(int siteID)
        {
            return ExecuteNonQuery("DELETE FROM {0} WHERE SiteID = {1};", AddProfix("Sites"), siteID);
        }

        public override Dictionary<string, SiteDomain> LoadSites()
        {
            Dictionary<string, SiteDomain> sites = new Dictionary<string, SiteDomain>(StringComparer.OrdinalIgnoreCase);
            using (var reader = ExecuteReader("SELECT * FROM {0};", AddProfix("Sites")))
            {
                while (reader.Read()) {
                    sites.Add(reader.GetString("DotLowerDomain"), new SiteDomain(reader));
                }
            }
            return sites;
        }

        public override bool SetSiteDefault(int siteID)
        {
            return ExecuteNonQuery("UPDATE {0} SET IsDefault = 0; UPDATE {0} SET IsDefault = 1 WHERE SiteID = '{1}';", AddProfix("Sites"), siteID);
        }

        public override SiteDomain GetSite(int siteID)
        {
            return ExecuteReader("SELECT * FROM {0} WHERE SiteID = {1};", AddProfix("Sites"), siteID).TGet<SiteDomain>();
        }
        #endregion

        #region sitesettings
        public override bool SaveSiteSettings(SiteSettings settings)
        {
            if(settings.SettingsID > 0)
                return ExecuteNonQuery("REPLACE INTO {0}(SettingsID, SettingsXML, ExtendSettings, LastModify)VALUES('{1}','{2}','{3}',now());", AddProfix("SiteSettings"), settings.SettingsID, Q(Globals.ConvertObjectToString(settings)), Q(settings.ToString()));
            return ExecuteNonQuery("INSERT INTO {0}(SettingsXML, ExtendSettings, LastModify)VALUES('{1}','{2}',now());", AddProfix("SiteSettings"), Q(Globals.ConvertObjectToString(settings)), Q(settings.ToString()));
        }

        public override SiteSettings GetSiteSettings(string dotLowerDomain)
        {
            SiteSettings settings = null;
            using (var reader = ExecuteReader("SELECT s.*, d.`Domain` FROM {0} s INNER JOIN {1} d ON s.SettingsID = d.SettingsID WHERE d.DotLowerDomain = '{2}' AND d.Enabled = 1;", AddProfix("SiteSettings"), AddProfix("Sites"), Q(dotLowerDomain))) {
                if (reader.Read())
                    settings = SiteSettings.TGet(reader);
                reader.Close();
            }
            return settings;
        }

        public override SiteSettings GetDefaultSettings()
        {
            SiteSettings settings = null;
            using (var reader = ExecuteReader("SELECT s.*, d.`Domain` FROM {0} s INNER JOIN {1} d ON s.SettingsID = d.SettingsID WHERE d.Enabled = 1 AND d.IsDefault = 1;", AddProfix("SiteSettings"), AddProfix("Sites"))) {
                if (reader.Read())
                    settings = SiteSettings.TGet(reader);
                reader.Close();
            }
            return settings;
        }
        #endregion

        #region routes
        public override Route GetRoute(int routeID)
        {
            return ExecuteReader("SELECT * FROM {0} WHERE RouteID = '{1}';", AddProfix("Routes"), routeID).TGet<Route>();
        }

        public override bool SaveRoute(Route route)
        {
            if(route.RouteID > 0)
                return ExecuteNonQuery("REPLACE INTO {0}(RouteID,AreaName,`Key`,Url,Defaults,Constraints,RouteHandler)VALUES('{1}','{2}','{3}','{4}','{5}','{6}','{7}');", AddProfix("Routes"), route.RouteID, Q(route.AreaName), Q(route.Key), Q(route.Url), Q(route.Defaults), Q(route.Constraints), Q(route.RouteHandlerString));
            return ExecuteNonQuery("INSERT INTO {0}(AreaName,`Key`,Url,Defaults,Constraints,RouteHandler)VALUES('{1}','{2}','{3}','{4}','{5}','{6}');", AddProfix("Routes"), Q(route.AreaName), Q(route.Key), Q(route.Url), Q(route.Defaults), Q(route.Constraints), Q(route.RouteHandlerString));
        }

        public override bool DeleteRoutes(string routeIDs)
        {
            return ExecuteNonQuery("DELETE FROM {0} WHERE RouteID IN ({1});", AddProfix("Routes"), Q(routeIDs));
        }

        public override Dictionary<string, Dictionary<string, Route>> LoadRoutes()
        {
            Dictionary<string, Dictionary<string, Route>> routes = new Dictionary<string, Dictionary<string, Route>>(StringComparer.OrdinalIgnoreCase);
            using (IDataReader reader = ExecuteReader("SELECT * FROM {0};",AddProfix("Routes")))
            {
                while (reader.Read())
                {
                    string key = reader.GetString("AreaName");
                    if (!routes.ContainsKey(key))
                        routes.Add(key, new Dictionary<string, Route>(StringComparer.OrdinalIgnoreCase));
                    routes[key].Add(reader.GetString("Key"), new Route(reader));
                }
                reader.Close();
            }
            return routes;
        }
        #endregion
    }
}